package org.minhnvt1.android.moviesearch.ui;

import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import org.minhnvt1.android.moviesearch.R;
import org.minhnvt1.android.moviesearch.io.FlushedInputStream;
import org.minhnvt1.android.moviesearch.model.Movie;
import org.minhnvt1.android.moviesearch.services.HttpRetriever;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MovieAdapter extends ArrayAdapter<Movie> {
	
	private HttpRetriever httpRetriever = new HttpRetriever();
	
	private ArrayList<Movie> movieDataItems;
	
	private Activity context;
	
	
	public MovieAdapter(Activity context, int textViewResourceId, ArrayList<Movie> movieDataItems) {
		super(context, textViewResourceId, movieDataItems);
		
		this.context = context;
		this.movieDataItems = movieDataItems;
		
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent){
		View view = convertView;
		
		if(view == null){
			LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			view = vi.inflate(R.layout.movie_data_row, null);
			
		}
		
		Movie movie = movieDataItems.get(position);
		
		if(movie != null){
			// name
			TextView nameTextView = (TextView) view.findViewById(R.id.name_text_view);
			nameTextView.setText(movie.name);
			
			//rating
			TextView ratingTextView = (TextView) view.findViewById(R.id.rating_text_view);
			ratingTextView.setText("Rating: " + movie.rating);
			
			//released
			TextView releasedTextView = (TextView) view.findViewById(R.id.released_text_view);
			releasedTextView.setText("Released Date: " + movie.released);
			
			//certification
			TextView certificationTextView = (TextView) view.findViewById(R.id.certification_text_view);
			certificationTextView.setText("Certification: " + movie.certification);
			
			//language
			TextView languageTextView = (TextView) view.findViewById(R.id.language_text_view);
			languageTextView.setText("Language: " + movie.language);
			
			//thumb image
			ImageView imageview = (ImageView) view.findViewById(R.id.movie_thumb_icon);
			String url = movie.retrieveThumbnail();
			if(url != null){
				Bitmap bitmap = fetchBimapFromCache(url);
				if (bitmap == null) {
					new BitmapDownloaderTask(imageview).execute(url);
				}else {
					imageview.setImageBitmap(bitmap);
				}
			}else {
				imageview.setImageBitmap(null);
			}
			
		}
		return view;
	}
	private LinkedHashMap<String, Bitmap> bitmapCache = new LinkedHashMap<String, Bitmap>();
	private void addBitmapToCache(String url, Bitmap bitmap) {
		if (bitmap != null) {
			synchronized (bitmapCache) {
				bitmapCache.put(url, bitmap);
			}
		}
	}
	private Bitmap fetchBimapFromCache(String url) {

		synchronized (bitmapCache) {
			final Bitmap bitmap = bitmapCache.get(url);
			if (bitmap != null) {
				bitmapCache.remove(url);
				bitmapCache.put(url, bitmap);
				return bitmap;
			}
		}
		return null;
	}
	private class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap>{
		
		private String url;
		private final WeakReference<ImageView> imageViewReference;
		
		public BitmapDownloaderTask(ImageView imageView){
			imageViewReference = new WeakReference<ImageView>(imageView);
		}
		@Override
		protected Bitmap doInBackground(String... params) {
			url = params[0];
			InputStream is = httpRetriever.retrieveStream(url);
			if (is == null){
				return null;
			}
			return BitmapFactory.decodeStream( new FlushedInputStream(is));
		}
		
		@Override
		protected void onPostExecute(Bitmap bitmap){
			if (isCancelled()){
				bitmap = null;
			}
			addBitmapToCache(url, bitmap);
			
			if (imageViewReference !=null) {
				ImageView imageView = imageViewReference.get();
				if (imageView != null) {
					imageView.setImageBitmap(bitmap);
					
				}
			}
		}
	}
}
